#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"

#include "image.h"


namespace vkinfer
{
	Image Image::imread(const std::string& image_path)
	{
		Image image;
		// stbi_set_flip_vertically_on_load(true);
		int width, height, channels;
		int force_channels = 3;
		unsigned char* data = stbi_load(image_path.c_str(), &width, &height, &channels, force_channels);
		if (data != nullptr)
		{
			image.data = data;
			image.width = width;
			image.height = height;
			image.channels = channels;
		}
		return image;
	}

	uint8_t Image::isample(uint32_t x, uint32_t y, uint32_t c) const 
	{
		return data[y * width * channels + x * channels + c];
	}

	float Image::sample(float x, float y, uint32_t c) const
	{
		// zero-padding
		if (x < 0 || x >= width - 1 || y < 0 || y >= height - 1)
			return 0.0f;

		int x1 = int(x);
		int x2 = x1 + 1;
		int y1 = int(y);
		int y2 = y1 + 1;
		float alpha = x - x1;
		float beta = y - y1;

		uint8_t v1 = isample(x1, y1, c);
		uint8_t v2 = isample(x1, y2, c);
		uint8_t v3 = isample(x2, y1, c);
		uint8_t v4 = isample(x2, y2, c);

		float v = v1 * (1 - alpha) * (1 - beta) + v2 * (1 - alpha) * beta + v3 * alpha * (1 - beta) +  v4 * alpha * beta;
		return v;
	}
}
